#pragma once

template<typename T>
class Checkbox : public UIElement
{
	Texture* m_borderTexture;
	Texture* m_checkTexture;
	Texture* m_highLight;
	Vertex3FRHWT m_vertices[4];
	std::string m_szText;
	CFont m_text;
	ui32 m_highLighted;
	T* m_instance;
	Tooltip mToolTip;
	bool mIsHovered;

	typedef void (T::*Callback)(Checkbox<T>*, ui32);
	Callback OnCheckChange;
public:
	Checkbox(T* instance, ui32 x, ui32 y, ui32 w, ui32 h, std::string szText = "", i32 texEntry = -1) : m_text("Fonts\\FrizQT__.ttf", "Friz Quadrata TT", 7, 15)
	{
		mIsHovered = false;
		OnCheckChange = 0;
		m_instance = instance;

		m_position.x = (float)x;
		m_position.y = (float)y;
		m_size.x = (float)w;
		m_size.y = (float)h;
		m_szText = sLocale.GetLocale(texEntry, szText);

		m_vertices[0].x = m_position.x;
		m_vertices[0].y = m_position.y;
		m_vertices[0].u = 0.0f;
		m_vertices[0].v = 0.0f;

		m_vertices[1].x = m_position.x + m_size.x;
		m_vertices[1].y = m_position.y;
		m_vertices[1].u = 0.8125f;
		m_vertices[1].v = 0.0f;

		m_vertices[2].x = m_position.x + m_size.x;
		m_vertices[2].y = m_position.y + m_size.y;
		m_vertices[2].u = 0.8125f;
		m_vertices[2].v = 0.8125f;

		m_vertices[3].x = m_position.x;
		m_vertices[3].y = m_position.y + m_size.y;
		m_vertices[3].u = 0.0f;
		m_vertices[3].v = 0.8125f;

		m_borderTexture = CTextureHandler::GetInstance()->GetTexture("Interface\\Buttons\\UI-Checkbox-Up.blp");
		m_checkTexture = CTextureHandler::GetInstance()->GetTexture("Interface\\Buttons\\UI-Checkbox-Check.blp");
		m_highLight = CTextureHandler::GetInstance()->GetTexture("Interface\\Buttons\\UI-Checkbox-Down.blp");

		m_state = 0;
		m_highLighted = 0;
	}

	std::string GetText() { return m_szText; }

	void SetTooltip(const std::string& message, const std::string& title)
	{
		mToolTip.SetMessage(message);
		mToolTip.SetTitle(title);
	}

	void Draw()
	{
		if(!m_visible)
			return;
		sD3D->SetFVF(VERTEX3FRHWT);
		sD3D->SetTexture(0, *m_borderTexture);	
		sD3D->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, m_vertices, sizeof(Vertex3FRHWT));

		if(m_highLighted)
		{
			sD3D->SetTexture(0, *m_highLight);
			sD3D->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, m_vertices, sizeof(Vertex3FRHWT));
		}

		if(mIsHovered)
		{
			if(!mToolTip.IsEmpty())
				sTooltipMgr.SetTooltip(mToolTip);
		}
		else
			sTooltipMgr.UnsetTooltip(mToolTip);

		if(m_state)
		{
			sD3D->SetTexture(0, *m_checkTexture);
			sD3D->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, m_vertices, sizeof(Vertex3FRHWT));
		}
		if(m_szText != "")
			m_text.DrawTextA(ui32(m_position.x + m_size.x + 5), ui32(m_position.y + 8), m_text.GetTextLen(m_szText), 30, m_szText);
	}

	void OnMouseMove(ui32 x, ui32 y, bool leftDown, bool rightDown)
	{
		mIsHovered = (x >= m_position.x && x <= (m_position.x + m_size.x) && y >= m_position.y && y <= (m_position.y + m_size.y));
	}

	void SetChecked(ui32 check)
	{
		m_state = check;
	}

	void SetOnCheckChange(Callback pFunc)
	{
		OnCheckChange = pFunc;
	}

	void MouseActivity(bool left, Vertex2F pos, bool up)
	{
		if(up && m_highLighted)
		{
			m_highLighted = 0;
			m_state = !m_state;
			if(m_instance && OnCheckChange)
				(m_instance->*OnCheckChange)(this, m_state);
		}
		else if(!up)
			m_highLighted = 1;
	}

	void ModPosition(i32 dx, i32 dy)
	{
		m_position.x += dx;
		m_position.y += dy;

		m_vertices[0].x = m_position.x;
		m_vertices[0].y = m_position.y;
		m_vertices[0].u = 0.0f;
		m_vertices[0].v = 0.0f;

		m_vertices[1].x = m_position.x + m_size.x;
		m_vertices[1].y = m_position.y;
		m_vertices[1].u = 0.8125f;
		m_vertices[1].v = 0.0f;

		m_vertices[2].x = m_position.x + m_size.x;
		m_vertices[2].y = m_position.y + m_size.y;
		m_vertices[2].u = 0.8125f;
		m_vertices[2].v = 0.8125f;

		m_vertices[3].x = m_position.x;
		m_vertices[3].y = m_position.y + m_size.y;
		m_vertices[3].u = 0.0f;
		m_vertices[3].v = 0.8125f;
	}

	void SetPosition(ui32 x, ui32 y)
	{
		m_position.x = x;
		m_position.y = y;

		m_vertices[0].x = m_position.x;
		m_vertices[0].y = m_position.y;
		m_vertices[0].u = 0.0f;
		m_vertices[0].v = 0.0f;

		m_vertices[1].x = m_position.x + m_size.x;
		m_vertices[1].y = m_position.y;
		m_vertices[1].u = 0.8125f;
		m_vertices[1].v = 0.0f;

		m_vertices[2].x = m_position.x + m_size.x;
		m_vertices[2].y = m_position.y + m_size.y;
		m_vertices[2].u = 0.8125f;
		m_vertices[2].v = 0.8125f;

		m_vertices[3].x = m_position.x;
		m_vertices[3].y = m_position.y + m_size.y;
		m_vertices[3].u = 0.0f;
		m_vertices[3].v = 0.8125f;
	}

	void* pData;
};